// 
//  Copyright 2011  reda
// 
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
// 
//        http://www.apache.org/licenses/LICENSE-2.0
// 
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
using System;
using ManiacMusicManager.Data.Core;
using ManiacMusicManager.Data.DAO.Ifaces;
using System.Collections.Generic;
using System.Collections;
namespace ManiacMusicManager.Data.Utils
{
	internal class SafeEnumerator<T> : IEnumerator<T>, IEnumerator, IDisposable
		where T : Entity
	{
		private readonly ISessionHolder holder;
		private readonly IEnumerator<T> enumerator;
		
		public SafeEnumerator (ISessionHolder holder, IEnumerator<T> enumerator)
		{
			this.holder = holder;
			this.enumerator = enumerator;
		}

		#region IEnumerator[T] implementation
		public T Current {
			get {
				try {
					holder.BeginSafeBlock();
					return enumerator.Current;
				}
				finally {
					holder.EndSafeBlock();
				}
			}
		}
		#endregion

		#region IEnumerator implementation
		public bool MoveNext ()
		{
			try {
				holder.BeginSafeBlock();
				return enumerator.MoveNext();
			}
			finally {
				holder.EndSafeBlock();
			}
		}

		public void Reset ()
		{
			try {
				holder.BeginSafeBlock();
				enumerator.Reset();
			}
			finally {
				holder.EndSafeBlock();
			}
		}

		object IEnumerator.Current {
			get {
				return this.Current;
			}
		}
		#endregion

		#region IDisposable implementation
		public void Dispose ()
		{
			try {
				holder.BeginSafeBlock();
				enumerator.Dispose();
			}
			finally {
				holder.EndSafeBlock();
			}
		}
		#endregion


	}
	
	internal class SafeEnumerable<T> : IEnumerable<T>, IEnumerable
		where T : Entity
	{
		private readonly ISessionHolder holder;
		private readonly IEnumerable<T> enumeration;
		
		public SafeEnumerable (ISessionHolder holder, IEnumerable<T> enumeration)
		{
			if (holder == null)
				throw new ArgumentNullException ("holder");
			if (enumeration == null)
				throw new ArgumentNullException ("enumeration");
			
			this.holder = holder;
			this.enumeration = enumeration;
		}

		#region IEnumerable[T] implementation
		public IEnumerator<T> GetEnumerator ()
		{
			try {
				holder.BeginSafeBlock();
				return new SafeEnumerator<T>(holder, enumeration.GetEnumerator());
			}
			finally {
				holder.EndSafeBlock();
			}
		}
		#endregion

		#region IEnumerable implementation
		IEnumerator IEnumerable.GetEnumerator ()
		{
			return this.GetEnumerator();
		}
		#endregion

	}
}

